using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.IO;
namespace E1
{
    delegate int Fun(Order x, Order y);
    [Serializable]
    public class Good
    {
        public string name { set; get; }
        public double price { set; get; }
        public Good(int kind, double price)
        {
            this.price = price;
            switch (kind)
            {
                case 0: name = "good1"; break;
                case 1: name = "good2"; break;
                case 2: name = "good3"; break;
                case 3: name = "good4"; break;
                case 4: name = "good5"; break;
            }
        }
        public int toint()
        {
            int res = 0;
            switch (name)
            {
                case "good1": res = 0;break;
                case "good2": res = 1; break;
                case "good3": res = 2; break;
                case "good4": res = 3; break;
                case "good5": res = 4; break;
            }
            return res;
        }
        public Good() { }
        public override string ToString()
        {
            return ("name：" + this.name + "price：" + this.price);
        }
    }
    [Serializable]
    public class Client
    {
        public string name { set; get; }
        public int age { set; get; }
        public string phoneNumber { set; get; }
        public Client(string name, int age, string phoneNumber)
        {
            this.name = name;
            this.age = age;
            this.phoneNumber = phoneNumber;
        }
        public Client()
        {

        }
        public override string ToString()
        {
            return ("name：" + this.name + "age：" + this.age + "电话号码:" + this.phoneNumber);
        }
    }
    [Serializable]
    public class OrderDetail
    {
        public Good good;
        public double amount;
        public double money;
        public OrderDetail(double amount, double price, int kind)
        {
            this.good = new Good(kind, price);
            this.amount = amount;
            this.money = amount * price;
        }
        public OrderDetail() { }
        public override string ToString()
        {
            return ("购买商品:" + good.ToString() + "数量:" + amount + "价值：" + money);
        }
        public override bool Equals(Object obj)
        {
            OrderDetail Detail = obj as OrderDetail;
            bool ss = (this.good.name == Detail.good.name);
            return ss;
        }//一种物品只有一个清单
        public override int GetHashCode()
        {
            return good.name.GetHashCode();
        }
    }
    [Serializable]
    public class Order
    {
        public string id { set; get; }
        public string date { set; get; }
        public double totalMoney { set; get; }
        public Client client;
        public List<OrderDetail> details;
        public override string ToString()
        {
            return ("订单号：" + id + "时间：" + date + "总金额" + totalMoney);
        }
        public string getGoods()
        {
            string str = string.Empty;
            foreach (var item in details)
            {
                str += item.good.name;
            }
            return str;
        }
        public void showOrder()
        {
            Console.WriteLine("订单号  客户  日期  总金额");
            Console.WriteLine("----------------------------");
            Console.WriteLine("{0} {1} {2} {3}", id, client.name, date, totalMoney);
            Console.WriteLine("客户详细信息：");
            Console.WriteLine(client.ToString());
            foreach (var item in details)
            {
                Console.WriteLine("订单明细：");
                Console.WriteLine(item.ToString());
            }
            Console.WriteLine("#####################################");
        }
        public Order(string id, string date)
        {
            this.id = id;
            this.date = date;
            details = new List<OrderDetail>();
        }
        public Order()
        {
        }
        public void changeClient(string name, int age, string phoneNumber)
        {
            client.age = age;
            client.name = name;
            client.phoneNumber = phoneNumber;
        }
        public double culculateMoney()
        {
            totalMoney = 0;
            foreach (var item in details)
            {
                totalMoney += item.money;
            }
            return totalMoney;
        }
        public override bool Equals(Object obj)
        {
            Order order = obj as Order;
            return order.id == this.id;
        }
        public override int GetHashCode()
        {
            return Convert.ToInt32(id);
        }
        public void setClient(string name, int age, string phoneNumber)
        {
            client = new Client(name, age, phoneNumber);
        }
        public void addDetails(double amount, double money, int kind)
        {
            details.Add(new OrderDetail(amount, money, kind));
        }
        public void addDetails(OrderDetail detail)
        {
            details.Add(detail);
        }
    }
    public class OrderService
    {
        public List<Order> orders;
        public OrderService()
        {
            orders = new List<Order>();
        }
        public string hello()
        {
            return "hello";
        }
        public void showAll()
        {
            foreach (var item in orders)
            {
                item.showOrder();
            }
        }
        public void Export()
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
            using (FileStream fs=new FileStream("order.xml",FileMode.OpenOrCreate))
            {
                xmlSerializer.Serialize(fs,orders);
                Console.WriteLine("Serialize from XML");
            }
        }
        public void Import()
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
            using (FileStream fs = new FileStream("order.xml", FileMode.OpenOrCreate))
            {
                List<Order> xmlorders=(List < Order >)xmlSerializer.Deserialize(fs);
                orders = xmlorders;
                Console.WriteLine("Deserialize from XML");
            }
        }
        public void addOrder(string id, string date, string name, string phoneNumber, int age,List<OrderDetail> details)
        {
            Order a = new Order(id, date);
            foreach (var item in orders)
            {
                if (item.Equals(a))
                {
                    Console.WriteLine("此订单已存在"); return;
                }
            }
            a.setClient(name, age, phoneNumber);
            foreach(var item in details)
            {
                a.details.Add(item);
            }
            a.culculateMoney();
            orders.Add(a);
        }

        public void removeOrder(string id)
        {
            var selected = from item in orders where item.id == id select item;
            // Order it = (Order)selected;
            Order it = new Order();
            foreach (var item in selected)
            {
                it = item;
            }
            orders.Remove(it);
        }
        public Order searchOrder(int chose, string str)
        {
            Order order=new Order();
            bool yes = false;
            switch (chose)
            {
                case 1:
                    var selected = from item in orders
                                   where item.id == str
                                   orderby item.totalMoney
                                   select item;

                    foreach (var it in selected)
                    {
                        yes = true;
                        it.showOrder();
                        order = it;
                        Console.WriteLine("---------------------");
                    }
                    break;
                case 2:
                    var selected2 = from item in orders
                                    where item.getGoods().Contains(str)
                                    orderby item.totalMoney
                                    select item;
                    foreach (var it in selected2)
                    {
                        yes = true;
                        it.showOrder();
                        order = it;
                        Console.WriteLine("---------------------");
                    }
                    break;
                case 3:
                    var selected3 = from item in orders
                                    where item.client.name == str
                                    orderby item.totalMoney
                                    select item;
                    foreach (var it in selected3)
                    {
                        yes = true;
                        it.showOrder();
                        order = it;
                        Console.WriteLine("---------------------");
                    }
                    break;
                case 4:
                    var selected4 = from item in orders
                                    where item.totalMoney == double.Parse(str)
                                    orderby item.totalMoney
                                    select item;
                    foreach (var it in selected4)
                    {
                        yes = true;
                        it.showOrder();
                        order = it;
                        Console.WriteLine("---------------------");
                    }
                    break;
            }
            if (yes == false)
            {
                order = null;
                Console.WriteLine("无此订单");
            }
            return order;
        }
        public void changeOrder(int chose, string id, string name, int age, string phoneNumber,List<OrderDetail> details)
        {
            Order it = searchOrder(1, id);
            if (chose == 1)
            {
                it.changeClient(name, age, phoneNumber);
            }else
            {
                orders.Remove(it);
                it.details.Clear();
                foreach (var item in details)
                {
                    it.addDetails(item.amount, item.money, item.good.toint());
                }
                it.culculateMoney();
                orders.Add(it);
            }
        }
        public void sortOrder(int i = 0)
        {
            switch (i)
            {
                case 0:
                    orders.Sort((x, y) => (int.Parse(x.id) - int.Parse(y.id))); break;
                case 1:
                    orders.Sort((x, y) => (int.Parse(x.date) - int.Parse(y.date))); break;
                case 2:
                    orders.Sort((x, y) => Convert.ToInt32(x.totalMoney - y.totalMoney)); break;
            }
            //Comparison<Order> comparison
            //orders.Sort(comparison);
            //orders.Sort((x,y)=> Convert.ToInt32(x.totalMoney-y.totalMoney));
        }

    }
    class Program
    {

        public static void changeOrder(OrderService service)
        {
            try
            {
                Console.WriteLine("请输入订单号");
                string id = Console.ReadLine();
                Console.WriteLine("请输入1或2,修改订单客户或明细");
                int chose = int.Parse(Console.ReadLine());
                List<OrderDetail> details = new List<OrderDetail>();
                    switch (chose)
                    {
                        case 1:
                            Console.WriteLine("请输入姓名");
                            string name = Console.ReadLine();
                            Console.WriteLine("请输入年龄");
                            int age = int.Parse(Console.ReadLine());
                            Console.WriteLine("请输入联系方式");
                            string phoneNumber = Console.ReadLine();
                            service.changeOrder(1,  id,  name,  age,  phoneNumber,null);
                            break;
                        case 2:
                            char conti = 'y'; double amount, money; int kind;
                            while (conti == 'y')
                            {
                                Console.WriteLine("请输入种类：");
                                kind = int.Parse(Console.ReadLine());
                                Console.WriteLine("请输入购买数量：");
                                amount = double.Parse(Console.ReadLine());
                                Console.WriteLine("请输入交易金额：");
                                money = double.Parse(Console.ReadLine());
                                OrderDetail detail = new OrderDetail(amount, money, kind);
                                bool unrepeat = true;
                                foreach (var item in details)
                                {
                                    if (item.Equals(detail))
                                    {
                                        unrepeat = false; break;
                                    }
                                }
                                if (unrepeat)
                                {
                                    details.Add(detail);
                                    Console.WriteLine("加入另一个明细表？ y/n ");
                                    conti = char.Parse(Console.ReadLine());
                                }
                                else
                                {
                                    Console.WriteLine("明细表重复，请重新输入 ");
                                }
                            }
                        service.changeOrder(2, id, null, 0, null, details);
                        break;
                    }
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("输入错误:");
                Console.WriteLine(ex.Message);
            }
        }
        public static void searchOrder(OrderService service)
        {
            Console.WriteLine("请输入1,2,3，或4，分别根据订单号、商品名称、客户、订单金额进行查询");
            int chose = int.Parse(Console.ReadLine()); bool yes = false;string str = "";
            switch (chose)
            {
                case 1:
                    Console.WriteLine("请输入订单号");
                    string id = Console.ReadLine(); str = id;
                    break;

                case 2:
                    Console.WriteLine("请输入商品名称");
                    string goodname = Console.ReadLine();
                    str = goodname;
                    break;
                case 3:
                    Console.WriteLine("请输入客户名");
                    string clientname = Console.ReadLine();
                    str = clientname;
                    break;
                case 4:
                    Console.WriteLine("请输入订单金额");
                    double money = double.Parse(Console.ReadLine());
                    str = money.ToString();
                    break;
            }
            service.searchOrder(chose,str);
        }
        public static void removeOrder(OrderService service)
        {
            try
            {
                Console.WriteLine("请输入订单号");
                string id = Console.ReadLine();
                service.removeOrder(id);
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("输入错误:");
                Console.WriteLine(ex.Message);
            }
        }
        public static void addOrder(OrderService service)
        {
            Console.WriteLine("请输入订单编号：");
            string id = Console.ReadLine();
            Console.WriteLine("请输入时间：");
            string date = Console.ReadLine();
            Console.WriteLine("输入订单明细：");
            Console.WriteLine("请输入客户姓名：");
            string name = Console.ReadLine();
            Console.WriteLine("请输入客户手机号码：");
            string phoneNumber = Console.ReadLine();
            Console.WriteLine("请输入客户年龄：");
            int age = int.Parse(Console.ReadLine());
            List<OrderDetail> details = new List<OrderDetail>();
            char conti = 'y'; double amount, money; int kind;
            while (conti == 'y')
            {
                Console.WriteLine("请输入种类：");
                kind = int.Parse(Console.ReadLine());
                Console.WriteLine("请输入购买数量：");
                amount = double.Parse(Console.ReadLine());
                Console.WriteLine("请输入交易价格：");
                money = double.Parse(Console.ReadLine());
                OrderDetail detail = new OrderDetail(amount, money, kind);
                
                bool unrepeat = true;
                foreach (var item in details)
                {
                    if (item.Equals(detail))
                    {
                        unrepeat = false; break;
                    }
                }
                if (unrepeat)
                {
                    details.Add(detail);
                    Console.WriteLine("加入另一个明细表？ y/n ");
                    conti = char.Parse(Console.ReadLine());
                }
                else
                {
                    Console.WriteLine("明细表重复，请重新输入 ");
                }

            }
            service.addOrder(id, date, name, phoneNumber, age, details);

        }
        static void Main(string[] args)
        {
            OrderService service = new OrderService();
            bool not_quit = true;
            while (not_quit)
            {
                Console.WriteLine("输入1增加订单，输入2删除订单，输入3查询订单\n输入4显示所有订单，输入5根据订单号为订单排序,输入6导出XML文件,输入7导入XML文件\n输入8改变订单，输入9退出");
                string choose1 = Console.ReadLine();
                switch (choose1)
                {
                    case "1": Program.addOrder(service); break;
                    case "2": Program.removeOrder(service); break;
                    case "3": Program.searchOrder(service); break;
                    case "4": service.showAll(); break;
                    case "5": service.sortOrder(0); break;
                    case "6": service.Export(); break;
                    case "7": service.Import(); break;
                    case "8": Program.changeOrder(service); break;
                    case "9": not_quit = false; break;
                    default: Console.WriteLine("输入错误"); break;
                }
            }


        }
    }
}
